﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using blackhouse.Aparts.Web.Model;
using blackhouse.Aparts.Web.View;
using blackhouse.BlackApart.Business.Apartments;
using blackhouse.BlackApart.Business.Opinions;

namespace blackhouse.Aparts.Web.Presenter {
    public class OpinionDetailsPresenter {

        #region Fields

        private readonly IOpinionDetailsView view;
        private readonly OpinionsModel model;

        private int opinionId;
        private IOpinion opinion;

        #endregion

        #region Constructors

        public OpinionDetailsPresenter(IOpinionDetailsView view, OpinionsModel model) {
            this.view = view;
            this.model = model;
        }

        #endregion

        #region Methods

        public void LoadView() {
            this.opinionId = this.view.OpinionId;
            if (this.opinionId > 0)
                this.opinion = this.model.GetOpinion(this.opinionId);

            if (this.opinion == null) {
                this.view.ShowNoOpinionInfo();
                return;
            }

            this.view.AverageRating = this.opinion.GetAverageRating();

            float simAvg = this.model.GetSimilarAverageRating(this.opinionId);

            if (simAvg > 0)
                this.view.SimilarAverageRating = this.model.GetSimilarAverageRating(this.opinionId);
            else
                this.view.SimilarAverageRating = -1;

            this.LoadOpinionCategories();

            DisplayOpinion displayOpinion = new DisplayOpinion(this.opinion);
            this.view.DisplayOpinion(displayOpinion);

            this.LoadAssociatedApartment();

            if (this.view.HaveOpinionAdminPriv) {
                this.view.EnableEditMode();
                if (!displayOpinion.IsPublic)
                    this.view.PublishButtonVisible = true;
            }
        }

        public void LoadSimilarOpinions() {
            var opinions = (from o in this.model.GetSimilarOpinions(this.opinionId) orderby o.PublishedDate descending select o).ToList();
            if (opinions.Count > 0)
                this.view.SimilarOpinions = opinions;
            else
                this.view.HideSimilarOpinions();
        }

        private void LoadAssociatedApartment() {
            IApartmentGroup group = this.opinion.GetAssociatedApartmentGroup();
            if (group != null)
                this.view.DisplayAssociatedApartment(group);
        }

        private void LoadOpinionCategories() {
            IOpinionCategory[] categories = this.model.GetOpinionCategories();
            Dictionary<string, double> list = new Dictionary<string, double>();
            foreach (IOpinionCategory category in categories) {
                string catName = category.Name;
                if (!string.IsNullOrEmpty(category.NameContinued))
                    catName = catName + " (" + category.NameContinued + ")";
                list.Add(catName, this.opinion.GetOpinionDetailValue(category.CategoryId));
            }
            var q = from entry in list orderby entry.Value descending select entry;
            this.view.CategoryValues = q.ToDictionary(pair => pair.Key, pair => pair.Value);
        }

        public void PublishOpinion() {
            this.opinionId = this.view.OpinionId;
            if (this.opinionId > 0) {
                if (this.opinion == null)
                    this.opinion = this.model.GetOpinion(this.opinionId);
                this.opinion.Publish(this.view.GetUserId());
                this.view.PublishButtonVisible = false;
                this.view.ShowPublishedInfo();
            }
        }

        public void SaveOpinion(string inPlus, string inMinus, string answer, bool withPublish) {
            this.opinionId = this.view.OpinionId;
            if (this.opinionId > 0) {
                if (this.opinion == null)
                    this.opinion = this.model.GetOpinion(this.opinionId);
                this.opinion.InPlusOpinion = inPlus;
                this.opinion.InMinusOpinion = inMinus;
                this.opinion.Answer = answer;
                bool status = this.opinion.Moderate(this.view.GetUserId());

                if (status && withPublish) {
                    this.opinion.Publish(this.view.GetUserId());
                    this.view.PublishButtonVisible = false;
                    this.view.ShowPublishedInfo();
                }
                else
                    this.view.ShowSavedInfo(status);


                DisplayOpinion displayOpinion = new DisplayOpinion(this.opinion);
                this.view.DisplayOpinion(displayOpinion);
                this.view.EnableEditMode();

            }
        }

        #endregion

    }
}